package com.devunion.salon.persistence;

import org.dbunit.DatabaseTestCase;
import org.dbunit.ext.mysql.MySqlDataTypeFactory;
import org.dbunit.operation.DatabaseOperation;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.DatabaseConfig;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.access.BeanFactoryLocator;
import org.springframework.beans.factory.access.SingletonBeanFactoryLocator;
import org.springframework.beans.factory.access.BeanFactoryReference;

import java.util.Properties;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.DriverManager;

/**
 * @author Viktar Liaskovich
 */
public abstract class BaseTestCase extends DatabaseTestCase {
    protected static Properties configuration;
    protected static BeanFactory context;


    static {
        BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance();
        BeanFactoryReference bf = bfl.useBeanFactory("com.devunion.salon.core");
        context = bf.getFactory();

        loadConfiguration();

        populateDB();
    }

    private static void populateDB() {
        IDatabaseConnection connection = null;
        IDataSet dataSet;
        try {
            connection = getDBConnection();
            dataSet = new FlatXmlDataSet(BaseTestCase.class.getClassLoader()
                        .getResourceAsStream("com/devunion/salon/persistence/delete-all.xml"));
            DatabaseOperation.DELETE.execute(connection, dataSet);
            DatabaseOperation.CLEAN_INSERT.execute(connection, getStaticDataSet());
        } catch (Exception e) {
            e.printStackTrace();
            fail(e.getMessage());
        } finally {
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    private static void loadConfiguration() {
        try {
            configuration = new Properties();
            configuration.load(BaseTestCase.class.getClassLoader()
                    .getResourceAsStream("system.properties"));
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
    }

    /**
     * Return DBUnit connection
     *
     * @return connection
     *
     * @throws Exception if any database error accures
     */
    protected IDatabaseConnection getConnection() throws Exception {
        return getDBConnection();
    }

    private static IDatabaseConnection getDBConnection()
        throws ClassNotFoundException, SQLException
    {
        Class.forName(configuration.getProperty("hibernate.connection.driver_class"));

        String user = configuration.getProperty("hibernate.connection.username");
        String password = configuration.getProperty("hibernate.connection.password");
        String url = configuration.getProperty("hibernate.connection.url");

        Connection connection = DriverManager.getConnection(url, user, password);

        IDatabaseConnection dbconnection = new DatabaseConnection(connection);

        DatabaseConfig config = dbconnection.getConfig();
        config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
            new MySqlDataTypeFactory());

        return dbconnection;
    }

    private static IDataSet getStaticDataSet() throws Exception {
        return new FlatXmlDataSet(BaseTestCase.class.getClassLoader()
                .getResourceAsStream("com/devunion/salon/persistence/static-test-data.xml"));
    }

    protected IDataSet getDataSet() throws Exception {
        return getStaticDataSet();
    }

    protected void setUp() throws Exception {
//        IDatabaseConnection connection = getConnection();
//        IDataSet dataSet = new FlatXmlDataSet(getClass().getClassLoader()
//                    .getResourceAsStream("se/powerforms/mop/test/delete-all.xml"));
//
//        try {
//            DatabaseOperation.DELETE.execute(connection, dataSet);
//            DatabaseOperation.CLEAN_INSERT.execute(connection, getStaticDataSet());
//        } finally {
//            connection.close();
//        }
    }
}
